﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Threading;
using Microsoft.Win32;

namespace All2Iso
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public delegate void UpdateProgressBarDelegate(DependencyProperty dp, Object value);
        List<IConverter> converters = new List<IConverter>();
        IConverter converter;
        int maxThreads;

        public MainWindow()
        {
            InitializeComponent();
            
            maxThreads = Environment.ProcessorCount * 2;

            UpdateProgressBarDelegate updatePbDelegate = new UpdateProgressBarDelegate(progressBar1.SetValue);
            converters.Add(new Converters.BinConverter(this));
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "All Image files (*.whatever)|*.*";

            Nullable<bool> res = dlg.ShowDialog();
            if (res != true)
            {
                return;
            }

            string filename = dlg.FileName;
            textBox1.Text = filename;
            if (checkIso())
            {
                MessageBox.Show("It is already an ISO file");
                return;
            }
            checkFile();
            button2.IsEnabled = false;
        }

        private bool checkIso()
        {
            FileStream fs = new FileStream(textBox1.Text, FileMode.Open, FileAccess.Read, FileShare.Read);
            fs.Seek(16 * 2048, SeekOrigin.Begin);

            byte[] sign = new byte[6] { 1, (byte)'C', (byte)'D', (byte)'0', (byte)'0', (byte)'1' };
            byte[] data = new byte[6];
            fs.Read((byte[])data, 0, 6);
            if (data.SequenceEqual(sign))
                return true;
            return false;
        }

        private void checkFile()
        {
            FileStream fs = new FileStream(textBox1.Text, FileMode.Open, FileAccess.Read, FileShare.Read);

            ThreadStart ts = delegate()
            {
                foreach (IConverter conv in converters)
                {
                    if (DoCheck(conv, fs, 1))
                    {
                        SetConverter(conv);
                        break;
                    }
                }
            };
            Thread t = new Thread(ts);
            t.Start();
        }

        public void SetConverter(IConverter c)
        {
            converter = c;
            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => this.button2.IsEnabled = true));
        }

        public void SetProgressLimit(int v)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => this.progressBar1.Maximum = v));
        }

        public void UpdateProgress(int v)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => this.progressBar1.Value = v));
        }

        public void ResetProgress()
        {
            Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => this.progressBar1.Value = 0));
            Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => this.progressBar1.Maximum = 100));
        }

        public static bool DoCheck(IConverter conv, FileStream fs, int level)
        {
            return conv.Check(fs, level);
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            String isoFn = textBox1.Text.Substring(0, textBox1.Text.Length - 3) + "iso";
            String inputFn = textBox1.Text;
            ThreadStart ts = delegate()
            {
                FileStream fs = new FileStream(inputFn, FileMode.Open, FileAccess.Read, FileShare.Read);
                FileStream output = new FileStream(isoFn, FileMode.CreateNew, FileAccess.Write, FileShare.None);
                converter.Convert(fs, output);
            };
            Thread t = new Thread(ts);
            t.Start();
        }

        private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
        {
            button2.IsEnabled = false;
        }
    }
}
